RxJS (Reactive Extensions for JavaScript) হলো একটি লাইব্রেরি যা Reactively ডেটা স্ট্রিমের সঙ্গে কাজ করার জন্য ব্যবহৃত হয়। এটি Observables ধারণা ব্যবহার করে, যা অ্যাসিঙ্ক্রোনাস এবং ইভেন্ট-ড্রিভেন প্রোগ্রামিং সহজ করে তোলে। Angular-এ RxJS এবং Observables ব্যাপকভাবে ব্যবহৃত হয়, বিশেষ করে HTTP রিকোয়েস্ট, রিয়েল-টাইম ডেটা স্ট্রিমিং, ইভেন্ট হ্যান্ডলিং, ফর্ম ভ্যালিডেশন ইত্যাদি ক্ষেত্রে।
RxJS একটি পপুলার লাইব্রেরি যা অ্যাসিঙ্ক্রোনাস ডেটা স্ট্রিম, ইভেন্ট, এবং ডেটা প্রসেসিংয়ের সাথে কাজ করার জন্য অপটিমাইজড। এটি Observables, Operators, এবং Schedulers এর উপর ভিত্তি করে কাজ করে, যা ডেটা ফ্লো এবং অ্যাসিঙ্ক্রোনাস স্টেট ম্যানেজমেন্টে একে কার্যকরী করে তোলে।
RxJS ব্যবহার করে আপনি বিভিন্ন ধরণের ডেটা স্ট্রিম তৈরি করতে পারেন এবং সেগুলির উপরে বিভিন্ন অপারেশন করতে পারেন, যেমন map, filter, merge, combine, switch, debounce, ইত্যাদি। এই সব অপারেটরগুলো ডেটাকে অনেক সহজভাবে ম্যানিপুলেট এবং হ্যান্ডল করার সুযোগ দেয়।
Observable হলো একটি ধরণ যা অ্যাসিঙ্ক্রোনাস ডেটা স্রোত (data stream) প্রস্তাব করে। এটি ডেটার প্রবাহের উপরে পরিচালনা করার একটি মাধ্যম এবং পরিবর্তনশীল ডেটার উপর নির্ভর করে অ্যাকশন নেয়।
Observables সাধারণত ব্যবহার করা হয়:
Observables এনক্যাপসুলেট করে অ্যাসিঙ্ক্রোনাস ডেটা সংগ্রহ এবং প্রসেসিং।
RxJS এর একটি গুরুত্বপূর্ণ বৈশিষ্ট্য হলো subscription। আপনি যখন একটি Observable তৈরি করেন, তখন সেটি তখনই কার্যকর হবে না যতক্ষণ না আপনি সেগুলিকে সাবস্ক্রাইব না করেন।
import { Observable } from 'rxjs';
// Observable তৈরি করা
const myObservable = new Observable(observer => {
observer.next('Hello');
observer.next('RxJS');
observer.complete();
});
// Observable এ সাবস্ক্রাইব করা
myObservable.subscribe({
next(value) { console.log(value); }, // Data emissions
complete() { console.log('Completed'); } // When observable completes
});
এখানে:
observer.next()
দিয়ে ডেটা পাঠানো হচ্ছে।observer.complete()
দিয়ে Observable কে complete করা হচ্ছে।subscribe()
এর মাধ্যমে এই Observable-এ সাবস্ক্রাইব করা হচ্ছে এবং ডেটা পাওয়া যাচ্ছে।RxJS অপারেটরস ব্যবহার করে আপনি Observables-এর উপর বিভিন্ন অপারেশন করতে পারেন, যেমন filtering, mapping, transforming ইত্যাদি।
map()
অপারেটরটি Observable ডেটাকে একটি নির্দিষ্ট ফর্ম্যাটে রূপান্তর করতে ব্যবহৃত হয়। এটি কোনো ইনপুট ডেটা গ্রহণ করে এবং একটি আউটপুট প্রদান করে।
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
of(1, 2, 3)
.pipe(
map(value => value * 2) // Each value will be multiplied by 2
)
.subscribe(result => console.log(result));
এখানে:
map(value => value * 2)
প্রতিটি উপাদানকে 2 গুণ করে রূপান্তরিত করবে।filter()
অপারেটরটি Observable থেকে কিছু মান ফিল্টার করে বের করতে ব্যবহৃত হয়।
import { of } from 'rxjs';
import { filter } from 'rxjs/operators';
of(1, 2, 3, 4, 5)
.pipe(
filter(value => value % 2 === 0) // Only even values will pass
)
.subscribe(result => console.log(result));
এখানে:
filter(value => value % 2 === 0)
শুধুমাত্র ইভেন নম্বরগুলো ফিল্টার করবে এবং কনসোল এ দেখাবে।debounceTime()
অপারেটরটি ইনপুট ভ্যালুগুলির মধ্যে সময় বিলম্ব রেখে শুধুমাত্র শেষ ইনপুটটিকে প্রসেস করতে সাহায্য করে। এটি বিশেষ করে ফর্ম ইনপুট ভ্যালিডেশন বা সার্চ বার ইভেন্টের জন্য কার্যকরী।
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
const searchBox = document.getElementById('searchBox');
fromEvent(searchBox, 'keyup')
.pipe(
debounceTime(500) // Waits for 500ms after the last keyup event
)
.subscribe(event => console.log('Search Query:', event));
এখানে:
debounceTime(500)
ব্যবহারকারী যখন টাইপ করবেন, তখন 500ms অপেক্ষা করবে এবং এরপর সার্চ কোয়েরি প্রসেস হবে।Angular অ্যাপ্লিকেশনে RxJS এবং Observables সাধারণত HTTP requests, event handling, এবং async operations এর জন্য ব্যবহৃত হয়।
Angular এর HttpClient সেবার মাধ্যমে HTTP রিকোয়েস্ট করতে হলে, সাধারণত Observables ব্যবহার করা হয়:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
return this.http.get('https://api.example.com/data');
}
}
এখানে:
http.get()
একটি Observable রিটার্ন করে, যা পরে subscribe()
করা হয় ডেটা পাওয়ার জন্য।RxJS এবং Observables Angular অ্যাপ্লিকেশনগুলিতে অ্যাসিঙ্ক্রোনাস অপারেশন এবং ডেটা স্ট্রিমিং সিস্টেম তৈরি করার জন্য অপরিহার্য। এর মাধ্যমে, আপনি ইভেন্ট, HTTP রিকোয়েস্ট, এবং অন্য যেকোনো ডেটা স্ট্রিমকে সহজেই ম্যানেজ করতে পারেন। RxJS-এর অপারেটরস ব্যবহার করে আপনি ডেটাকে ফিল্টার, ট্রান্সফর্ম, এবং কম্বাইন করতে পারেন, যা অ্যাপ্লিকেশনটির পারফরম্যান্স ও কোড ম্যানেজমেন্টে অনেক সহায়ক।
RxJS (Reactive Extensions for JavaScript) হল একটি লাইব্রেরি যা প্রতিক্রিয়া ভিত্তিক প্রোগ্রামিং (Reactive Programming) ধারণাকে বাস্তবায়িত করে। এটি অবজার্ভেবল (Observable) স্ট্রিম এবং অপারেটরস (Operators) এর মাধ্যমে অ্যাসিনক্রোনাস ডেটা স্ট্রিম এবং ইভেন্টগুলির সাথে কাজ করতে ব্যবহৃত হয়। RxJS Angular অ্যাপ্লিকেশনগুলিতে ডেটা স্ট্রিম, ইভেন্ট এবং অ্যাসিনক্রোনাস অপারেশনগুলি পরিচালনা করার জন্য একটি অত্যন্ত শক্তিশালী টুল।
Angular-এ RxJS ব্যাপকভাবে ব্যবহৃত হয়, বিশেষ করে HTTP রিকোয়েস্ট, ইভেন্ট হ্যান্ডলিং, টেমপ্লেট ডেটা বাইন্ডিং এবং ইউজার ইনপুটের ক্ষেত্রে।
RxJS মূলত Observables এর সাথে কাজ করে, যা ডেটা স্ট্রিম বা ইভেন্টের ধারাবাহিকতা কে প্রতিক্রিয়া ভিত্তিক ভাবে পরিচালনা করে। এতে ডেটা প্রবাহকে স্নিগ্ধ এবং সহজভাবে প্রসেস করা যায়, যেমন একটি ইউজার ইনপুট বা সার্ভার থেকে আসা ডেটা স্ট্রিম।
RxJS এর মধ্যে কিছু গুরুত্বপূর্ণ উপাদান রয়েছে:
Observable একটি ডেটা স্ট্রিম বা ইভেন্টের সিরিজ যা অ্যাসিনক্রোনাস অপারেশন বা ইভেন্টের ফলাফল হতে পারে। এটি ভবিষ্যতের মান প্রদান করতে সক্ষম এবং এটি একাধিক মান (ডেটা) প্রাপ্তি করতে পারে। অবজার্ভেবল সাধারণত HTTP রিকোয়েস্ট, ইউজার ইনপুট, টাইমার, বা ইভেন্টগুলির জন্য ব্যবহৃত হয়।
import { Observable } from 'rxjs';
const observable = new Observable(subscriber => {
subscriber.next('Hello');
subscriber.next('World');
subscriber.complete();
});
observable.subscribe({
next(value) { console.log(value); },
complete() { console.log('Completed!'); }
});
এখানে, Observable একটি স্ট্রিম তৈরি করে, যা next()
মেথড দ্বারা ভ্যালু পাঠায় এবং complete()
মেথডের মাধ্যমে সম্পূর্ণ হয়।
Observer একটি অবজার্ভেবল থেকে আসা ডেটা বা ইভেন্টকে গ্রহণ করে। এটি তিনটি মেথডে ডেটা গ্রহণ করে: next()
, error()
, এবং complete()
।
const observer = {
next: value => console.log('Received:', value),
error: err => console.log('Error:', err),
complete: () => console.log('Observable complete')
};
এখানে, Observer অবজার্ভেবল থেকে ডেটা গ্রহণ করবে এবং next()
, error()
, অথবা complete()
এর মাধ্যমে ফলাফল দেখাবে।
RxJS অপারেটরগুলি অবজার্ভেবলগুলির উপর বিভিন্ন রকম অপারেশন প্রয়োগ করতে ব্যবহৃত হয়। এগুলি অনেক ধরনের হতে পারে, যেমন ডেটা ফিল্টার করা, ম্যাপ করা, মার্জ করা ইত্যাদি। কিছু সাধারণ অপারেটরের মধ্যে রয়েছে:
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
const numbers = of(1, 2, 3, 4, 5);
numbers.pipe(
map(value => value * 2)
).subscribe(value => console.log(value));
এখানে, map()
অপারেটর ব্যবহার করে প্রত্যেকটি মানকে ২ দিয়ে গুণ করা হয়েছে।
Subscription একটি অবজার্ভেবল সাবস্ক্রাইব করার পদ্ধতি। এটি অবজার্ভেবল থেকে ডেটা গ্রহণ করতে ব্যবহৃত হয় এবং unsubscribe()
মেথডের মাধ্যমে অবজার্ভেবল সাবস্ক্রিপশন বাতিল করা যায়।
const subscription = observable.subscribe({
next(value) { console.log(value); },
complete() { console.log('Complete!'); }
});
// সাবস্ক্রিপশন বন্ধ করা
subscription.unsubscribe();
এখানে, সাবস্ক্রাইব করার পরে unsubscribe()
মেথড ব্যবহার করে সাবস্ক্রিপশন বন্ধ করা হয়েছে।
Angular অ্যাপ্লিকেশনগুলিতে RxJS ব্যাপকভাবে ব্যবহৃত হয়, বিশেষত HTTP রিকোয়েস্ট এবং ফর্ম ইভেন্টগুলি নিয়ন্ত্রণ করার জন্য। Angular এর HTTP ক্লায়েন্টও RxJS ব্যবহার করে, যেটি HTTP রিকোয়েস্টের ফলাফলকে Observable হিসেবে প্রদান করে। এছাড়া, Angular এর ফর্ম সিস্টেম এবং রাউটিং সিস্টেমেও RxJS অন্তর্ভুক্ত রয়েছে।
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
return this.http.get('https://api.example.com/data');
}
}
এখানে, getData()
মেথডটি HTTP রিকোয়েস্টের ফলাফলকে Observable হিসেবে প্রদান করছে, এবং এই Observable কে Angular টেমপ্লেটে সাবস্ক্রাইব করা যায়।
RxJS একটি শক্তিশালী টুল যা Angular অ্যাপ্লিকেশনগুলিকে আরও স্কেলেবল এবং পারফর্ম্যান্ট করে তোলে।
Angular-এ Observables, Operators, এবং Subjects খুবই গুরুত্বপূর্ণ। এগুলি RxJS (Reactive Extensions for JavaScript) লাইব্রেরি থেকে আসে, যা Angular-এ রিএ্যাক্টিভ প্রোগ্রামিং এবং ডাটা স্ট্রীম হ্যান্ডলিং এর জন্য ব্যবহৃত হয়। এর মাধ্যমে অ্যাসিনক্রোনাস ডাটা স্ট্রীম (যেমন HTTP রিকোয়েস্ট, ইউজার ইন্টারঅ্যাকশন, ইভেন্টস) খুবই সহজে ম্যানেজ করা সম্ভব।
Observables হলো এমন একধরনের ডাটা স্ট্রীম যা অ্যাসিনক্রোনাসভাবে ডেটা সরবরাহ করে। এটি ব্যবহার করে আমরা স্ট্রীমিং ডেটার সাথে ইন্টারঅ্যাক্ট করতে পারি এবং প্রয়োজনীয় ডেটা গ্রহণ, পরিবর্তন বা অপারেশন করতে পারি।
Observables প্রাথমিকভাবে Angular-এ HTTP রিকোয়েস্ট, ইউজার ইন্টারঅ্যাকশন, বা টাইমারগুলোর মাধ্যমে ডেটা রিসিভ করতে ব্যবহৃত হয়।
import { Observable } from 'rxjs';
// একটি সিম্পল Observable তৈরি
const observable = new Observable(subscriber => {
subscriber.next('Hello');
subscriber.next('World');
subscriber.complete();
});
observable.subscribe({
next(value) { console.log(value); },
complete() { console.log('Complete!'); }
});
এখানে, observable
একটি স্ট্রীম তৈরি করে যেটি দুইটি next
ইভেন্ট পাঠাবে এবং তারপর complete
কল করবে।
Operators হলো RxJS এর ফাংশন যা Observable এর উপরে বিভিন্ন ধরনের অপারেশন সম্পাদন করে। অপারেটরগুলো map, filter, mergeMap, switchMap ইত্যাদি হিসেবে উপলব্ধ থাকে। এগুলোর মাধ্যমে আপনি Observable এর মান পরিবর্তন, ফিল্টার, এবং অন্যান্য নানা অপারেশন করতে পারেন।
map: Observable এর প্রতিটি মানে একটি ট্রান্সফরমেশন বা পরিবর্তন আনতে ব্যবহৃত হয়।
উদাহরণ:
import { map } from 'rxjs/operators';
observable.pipe(
map(value => value.toUpperCase())
).subscribe(value => console.log(value));
এখানে, map
অপারেটরটি Observable থেকে পাওয়া মানগুলোর প্রতিটি ভ্যালু uppercase-এ পরিবর্তন করবে।
filter: Observable থেকে কিছু নির্দিষ্ট শর্তে মান ফিল্টার করতে ব্যবহৃত হয়।
উদাহরণ:
import { filter } from 'rxjs/operators';
observable.pipe(
filter(value => value === 'Hello')
).subscribe(value => console.log(value));
এখানে, filter
অপারেটরটি শুধুমাত্র 'Hello'
ভ্যালু এলিমেন্টকে গ্রহণ করবে এবং অন্য সবকে বাদ দিবে।
switchMap: একটি নতুন Observable স্ট্রীম তৈরির জন্য ব্যবহৃত হয় এবং পুরানো Observable কে অবহেলা করে নতুন Observable থেকে ডেটা নেয়।
উদাহরণ:
import { switchMap } from 'rxjs/operators';
observable.pipe(
switchMap(value => {
return new Observable(subscriber => {
subscriber.next(`${value} switched!`);
subscriber.complete();
});
})
).subscribe(value => console.log(value));
mergeMap: এটি একটি Observable থেকে আরেকটি Observable তৈরি করে এবং সমস্ত Observable থেকে আসা ভ্যালু মার্জ করে।
উদাহরণ:
import { mergeMap } from 'rxjs/operators';
observable.pipe(
mergeMap(value => {
return new Observable(subscriber => {
subscriber.next(`${value} merged!`);
subscriber.complete();
});
})
).subscribe(value => console.log(value));
Subjects হল একটি বিশেষ ধরনের Observable যা Observer এবং Observable উভয়ের মতো আচরণ করে। এটি একাধিক সাবস্ক্রাইবারকে একই ডাটা সরবরাহ করতে পারে এবং একাধিক সাবস্ক্রাইবারকে ডেটা পাঠানোর ক্ষমতা রাখে।
এটি সাধারণত যখন একাধিক কনজিউমারকে একই ডাটা শেয়ার করতে হয় তখন ব্যবহার করা হয়। সাধারণভাবে তিনটি ধরনের Subjects রয়েছে:
Subject
:import { Subject } from 'rxjs';
const subject = new Subject();
// Subscriber 1
subject.subscribe(value => {
console.log(`Subscriber 1: ${value}`);
});
// Subscriber 2
subject.subscribe(value => {
console.log(`Subscriber 2: ${value}`);
});
// Emit values
subject.next('Hello');
subject.next('World');
এখানে, Subject
দুটি সাবস্ক্রাইবারকে একই ডেটা পাঠাচ্ছে। দুজনেই "Hello"
এবং "World"
দেখবে।
import { BehaviorSubject } from 'rxjs';
const behaviorSubject = new BehaviorSubject('Initial Value');
behaviorSubject.subscribe(value => {
console.log(`Subscriber 1: ${value}`);
});
// Emit a new value
behaviorSubject.next('Updated Value');
// New Subscriber will get the last emitted value
behaviorSubject.subscribe(value => {
console.log(`Subscriber 2: ${value}`);
});
এখানে, BehaviorSubject
সাবস্ক্রাইবার ২ কে "Updated Value"
পাঠাবে, কারণ এটি সর্বশেষ মান রাখে।
Angular-এ RxJS ব্যবহার করে আপনি অ্যাসিনক্রোনাস ডেটা ম্যানেজমেন্ট এবং রিএ্যাক্টিভ প্রোগ্রামিং সহজে করতে পারেন।
RxJS (Reactive Extensions for JavaScript) হল একটি লাইব্রেরি যা অ্যাসিনক্রোনাস ডেটা স্ট্রিম এবং ইভেন্ট পরিচালনা করতে সাহায্য করে। এটি Angular অ্যাপ্লিকেশনে ডেটা ফেচিং, সাবস্ক্রিপশন, ইভেন্ট হ্যান্ডলিং, এবং স্ট্রিম প্রক্রেসিংয়ের জন্য ব্যবহৃত হয়। RxJS অপারেটরগুলি আমাদের ডেটা স্ট্রিমগুলিকে ট্রান্সফর্ম, ফিল্টার, এবং কম্পোজ করতে সাহায্য করে। এখানে আমরা কিছু সাধারণ RxJS অপারেটরগুলির ব্যাখ্যা এবং ব্যবহার দেখব যেমন map
, filter
, mergeMap
, concatMap
, switchMap
ইত্যাদি।
map অপারেটরটি ইনপুট ভ্যালুর উপর কোন ট্রান্সফর্মেশন বা রূপান্তর প্রয়োগ করে এবং একটি নতুন ভ্যালু রিটার্ন করে।
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
const source$ = of(1, 2, 3, 4);
const mapped$ = source$.pipe(map(value => value * 2));
mapped$.subscribe(value => console.log(value)); // Output: 2, 4, 6, 8
এখানে, map
অপারেটরটি প্রতিটি ইনপুট ভ্যালুর উপর *2
অপারেশন প্রয়োগ করছে।
filter অপারেটরটি শুধুমাত্র সেই ভ্যালুগুলিকে পাস করে যেগুলি একটি নির্দিষ্ট শর্তে খাপ খায়। এটি স্ট্রিমের ডেটাকে ফিল্টার করতে ব্যবহৃত হয়।
import { of } from 'rxjs';
import { filter } from 'rxjs/operators';
const source$ = of(1, 2, 3, 4, 5);
const filtered$ = source$.pipe(filter(value => value % 2 === 0));
filtered$.subscribe(value => console.log(value)); // Output: 2, 4
এখানে, filter
অপারেটরটি শুধু এমন ভ্যালু পাস করবে যেগুলি even
(যুগল সংখ্যা)।
mergeMap অপারেটরটি ইনপুট স্ট্রিমের প্রতিটি ভ্যালুতে একটি নতুন Observable রিটার্ন করে এবং সমস্ত Observable কে একত্রে মর্জ (merge) করে। এটি একাধিক সাবস্ক্রিপশন তৈরি করে, ফলে এটি বিভিন্ন অ্যাসিনক্রোনাস অপারেশনের ফলাফল একসাথে পেতে সাহায্য করে।
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
const source$ = of(1, 2, 3);
const merged$ = source$.pipe(
mergeMap(value => of(value * 10)) // প্রতিটি ভ্যালুর জন্য একটি নতুন Observable
);
merged$.subscribe(value => console.log(value)); // Output: 10, 20, 30
এখানে, mergeMap
প্রতিটি ইনপুট ভ্যালুর জন্য একটি নতুন Observable তৈরি করে এবং সমস্ত ফলাফল একসাথে রিটার্ন করে।
concatMap অপারেটরটি একে একে (sequentially) একাধিক Observable এক্সিকিউট করতে ব্যবহৃত হয়। এটি এক সময়ে একটি ইনপুট Observable-কে প্রক্রিয়া করবে এবং পরবর্তী Observable ততক্ষণে শুরু হবে না যতক্ষণ না প্রথমটি শেষ হয়।
import { of } from 'rxjs';
import { concatMap } from 'rxjs/operators';
const source$ = of(1, 2, 3);
const concatMapped$ = source$.pipe(
concatMap(value => of(value * 10))
);
concatMapped$.subscribe(value => console.log(value)); // Output: 10, 20, 30
এখানে, concatMap
প্রতিটি ভ্যালু ইনপুট স্ট্রিমের পর sequentially প্রসেস করবে।
switchMap অপারেটরটি একটি নতুন Observable রিটার্ন করে এবং আগের Observable-কে সাবস্ক্রাইব করতে বাধা দেয়। যদি একটি নতুন ইনপুট আসা হয়, এটি পুরোনো Observable কে ক্যান্সেল করে এবং নতুন Observable এর সাথে কাজ শুরু করে।
import { of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
const source$ = of('A', 'B', 'C');
const switched$ = source$.pipe(
switchMap(value => of(value + ' processed'))
);
switched$.subscribe(value => console.log(value)); // Output: 'A processed', 'B processed', 'C processed'
এখানে, switchMap
প্রতিটি নতুন ইনপুট আসলে আগের Observable-কে ক্যান্সেল করে নতুন Observable-কে প্রসেস করবে।
debounceTime অপারেটরটি ইনপুট স্ট্রিমে ডিলে (delay) করে। এটি ডেটার ফ্লাকচুয়েশন কমাতে বা অতিরিক্ত API কল এড়াতে ব্যবহৃত হয়। উদাহরণস্বরূপ, যখন একজন ব্যবহারকারী ইনপুট ফিল্ডে টাইপ করছে, তখন প্রতিটি টাইপের পরে API কল না হয়ে একটি নির্দিষ্ট সময় পর কল করা হয়।
import { of } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
const source$ = of('hello', 'hi', 'how are you');
const debounced$ = source$.pipe(
debounceTime(1000) // 1 সেকেন্ড ডিলে
);
debounced$.subscribe(value => console.log(value));
এখানে, debounceTime
অপারেটরটি ইনপুটের মধ্যে ১ সেকেন্ড ডিলে যুক্ত করবে।
distinctUntilChanged অপারেটরটি শুধুমাত্র সেই ভ্যালুগুলোকে পাস করবে যেগুলি পূর্ববর্তী ভ্যালুর সাথে আলাদা। এটি ডুপ্লিকেট ইনপুট এড়াতে ব্যবহৃত হয়।
import { of } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
const source$ = of(1, 1, 2, 3, 3, 4, 5);
const distinct$ = source$.pipe(
distinctUntilChanged() // পূর্ববর্তী ভ্যালুর সাথে মিল না হলে পাস করবে
);
distinct$.subscribe(value => console.log(value)); // Output: 1, 2, 3, 4, 5
এখানে, distinctUntilChanged
একই মানের পুনরাবৃত্তি এড়াবে।
RxJS অপারেটরগুলো Angular অ্যাপ্লিকেশনে ডেটা স্ট্রিম হ্যান্ডলিং এবং অ্যাসিনক্রোনাস অপারেশনগুলো সহজ করে। এর মাধ্যমে আপনি ডেটাকে ট্রান্সফর্ম, ফিল্টার, এবং ম্যানিপুলেট করতে পারেন। map
, filter
, mergeMap
, concatMap
, switchMap
, debounceTime
, distinctUntilChanged
ইত্যাদি অপারেটরগুলি সাধারণত ব্যবহৃত হয়। এগুলির দক্ষ ব্যবহার অ্যাঙ্গুলার অ্যাপ্লিকেশনগুলোতে শক্তিশালী এবং কার্যকর ডেটা ফ্লো তৈরি করতে সাহায্য করে।
Angular অ্যাপ্লিকেশনগুলোতে অ্যাসিঙ্ক্রোনাস অপারেশন অনেক গুরুত্বপূর্ণ, বিশেষ করে যখন আপনি ডেটা ফেচিং, সার্ভার থেকে রেসপন্স পাওয়া, ফাইল আপলোড বা অন্য যেকোনো টাইম-টেকিং প্রসেস পরিচালনা করতে চান। Angular এই অ্যাসিঙ্ক্রোনাস কাজগুলো পরিচালনার জন্য মূলত RxJS (Reactive Extensions for JavaScript) ব্যবহার করে।
RxJS এর মাধ্যমে আপনি Observables পরিচালনা করতে পারেন এবং বিভিন্ন অপারেটর ব্যবহার করে ডেটার ফ্লো ম্যানেজ করতে পারেন। অ্যাসিঙ্ক্রোনাস অপারেশন হ্যান্ডলিংয়ের ক্ষেত্রে RxJS অনেক শক্তিশালী টুল সরবরাহ করে, যেমন map
, mergeMap
, switchMap
, concatMap
, catchError
ইত্যাদি।
RxJS ব্যবহার করে অ্যাসিঙ্ক্রোনাস অপারেশনগুলোকে আরও কার্যকরভাবে হ্যান্ডল করা যায়। RxJS আপনাকে Observable এবং Operators দিয়ে ডেটার ফ্লো সহজেই নিয়ন্ত্রণ করতে সাহায্য করে।
Angular অ্যাপ্লিকেশনে HTTP কল করার জন্য HttpClient ব্যবহার করা হয়। এটি RxJS এর Observable
রিটার্ন করে, যার মাধ্যমে অ্যাসিঙ্ক্রোনাস ডেটা ফেচিং করা হয়।
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
return this.http.get('https://api.example.com/data');
}
}
এখানে, getData()
মেথডটি Observable
রিটার্ন করে যা HTTP রেসপন্স আসার পর আপনার অ্যাপ্লিকেশনকে ডেটা প্রদান করবে।
RxJS এর বিভিন্ন অপারেটর ব্যবহার করে অ্যাসিঙ্ক্রোনাস ডেটা ট্রান্সফর্ম, ফিল্টার বা অন্যান্য ক্রিয়াকলাপ করা যায়।
HTTP কলের মাধ্যমে ডেটা পেতে RxJS এর subscribe()
মেথড ব্যবহার করতে হয়। আপনি async
পাইপও ব্যবহার করতে পারেন।
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-data',
templateUrl: './data.component.html',
styleUrls: ['./data.component.css']
})
export class DataComponent implements OnInit {
data: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.getData().subscribe(
(response) => {
this.data = response;
},
(error) => {
console.error('Error fetching data', error);
}
);
}
}
এখানে subscribe()
মেথড ব্যবহার করে HTTP রেসপন্স অ্যাসিঙ্ক্রোনাসভাবে হ্যান্ডল করা হয়েছে এবং রেসপন্স পাওয়ার পর this.data
তে সেট করা হয়েছে।
map
অপারেটর ব্যবহার করে আপনি Observable এর রেসপন্স ডেটাকে পরিবর্তন করতে পারেন।
import { map } from 'rxjs/operators';
this.dataService.getData().pipe(
map((data) => {
return data.map(item => item.name); // এখানে শুধু 'name' প্রপার্টি নিয়ে আসা হয়েছে
})
).subscribe((modifiedData) => {
this.data = modifiedData;
});
যেকোনো ত্রুটি (Error) হ্যান্ডল করতে catchError
অপারেটর ব্যবহার করা হয়।
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';
this.dataService.getData().pipe(
catchError(error => {
console.error('Error:', error);
return of([]); // এর মাধ্যমে আপনি একটি ডিফল্ট ভ্যালু রিটার্ন করতে পারেন
})
).subscribe((data) => {
this.data = data;
});
একটি অ্যাসিঙ্ক্রোনাস অপারেশন থেকে অন্য অ্যাসিঙ্ক্রোনাস অপারেশন চালানোর জন্য mergeMap
ব্যবহার করা হয়। এটি আগের অপারেশনগুলো ক্যানসেল না করে সবগুলো সম্পন্ন হতে দেয়।
import { mergeMap } from 'rxjs/operators';
this.dataService.getData().pipe(
mergeMap((data) => {
return this.anotherService.getAdditionalData(data.id); // নতুন HTTP কল করা হচ্ছে
})
).subscribe((finalData) => {
this.data = finalData;
});
যখন নতুন অ্যাসিঙ্ক্রোনাস অপারেশন শুরু করতে চান এবং আগের অপারেশনগুলো ক্যানসেল করতে চান, তখন switchMap
ব্যবহার করা হয়।
import { switchMap } from 'rxjs/operators';
this.dataService.getData().pipe(
switchMap((data) => {
return this.anotherService.getAdditionalData(data.id); // আগের অপারেশন ক্যানসেল হবে এবং নতুন অপারেশন শুরু হবে
})
).subscribe((finalData) => {
this.data = finalData;
});
async
পাইপ ব্যবহারAngular টেম্পলেটের মধ্যে অ্যাসিঙ্ক্রোনাস ডেটা হ্যান্ডল করতে আপনি async
পাইপ ব্যবহার করতে পারেন। এটি Observable সাবস্ক্রাইব করে এবং রেসপন্স পাওয়ার পর অটোমেটিকভাবে ভিউতে রেন্ডার করে।
<div *ngIf="data$ | async as data">
<p>{{ data.name }}</p>
</div>
এখানে, data$
একটি Observable এবং async
পাইপ এটিকে সাবস্ক্রাইব করে এবং কম্পোনেন্টে ডেটা রেন্ডার করবে।
map
, catchError
, switchMap
) ব্যবহার করে ডেটা ট্রান্সফর্ম, ত্রুটি হ্যান্ডলিং এবং অ্যাসিঙ্ক্রোনাস ফ্লো নিয়ন্ত্রণ করা যায়।async
পাইপ ব্যবহার করে অ্যাসিঙ্ক্রোনাস ডেটা রেন্ডার করা যায়।Angular অ্যাপ্লিকেশনগুলোতে অ্যাসিঙ্ক্রোনাস ডেটা হ্যান্ডলিংয়ের জন্য RxJS অত্যন্ত শক্তিশালী টুল, যা ডেটা ফেচিং এবং ব্যবহারকারী ইন্টারফেসে প্রদর্শন সহজ করে তোলে।
RxJS (Reactive Extensions for JavaScript) হল একটি লাইব্রেরি যা asynchronous ডেটা স্ট্রিম এবং ইভেন্ট-ভিত্তিক প্রোগ্রামিং পরিচালনা করার জন্য ব্যবহৃত হয়। Angular অ্যাপ্লিকেশনগুলোতে RxJS ব্যাপকভাবে ব্যবহৃত হয়, বিশেষ করে HTTP অনুরোধ, ফর্ম ভ্যালিডেশন, এবং ইভেন্ট হ্যান্ডলিংয়ে।
RxJS তে ত্রুটি হ্যান্ডলিং একটি গুরুত্বপূর্ণ অংশ। যখন আমরা Observable স্ট্রিম ব্যবহার করি, তখন বিভিন্ন কারণে ত্রুটি (error) আসতে পারে, যেমন নেটওয়ার্ক সমস্যা, সার্ভার ত্রুটি, অথবা ইউজার ইন্টারঅ্যাকশন থেকে।
RxJS-এ catchError
এবং throwError
এর মাধ্যমে ত্রুটি হ্যান্ডলিং করা হয়। catchError
অপারেটরটি স্ট্রিমে ত্রুটি হলে তার পরবর্তী অপারেশন কিভাবে পরিচালনা হবে তা নির্ধারণ করে।
catchError
: এই অপারেটরটি যখন Observable এর মধ্যে ত্রুটি ঘটবে তখন তার পরবর্তী স্ট্রিমে ত্রুটি ধরতে সাহায্য করে।throwError
: ত্রুটি ঘটানোর জন্য এটি ব্যবহৃত হয়, যেমন নির্দিষ্ট ত্রুটি ছুড়ে দেয়া।catchError
অপারেটর ব্যবহারcatchError
অপারেটরটি ত্রুটি গ্রহণ এবং সেগুলিকে হ্যান্ডল করতে ব্যবহৃত হয়। এটি একটি নতুন Observable রিটার্ন করে যা ত্রুটির পরে পুনরায় স্ট্রিম চালু রাখে।
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getData(): Observable<any> {
return this.http.get('https://api.example.com/data')
.pipe(
catchError(error => {
console.error('Error occurred:', error);
// আপনি এখানে Error Handling করতে পারেন যেমন Alert বা Message প্রেরণ করা
return throwError(() => new Error('Something went wrong!'));
})
);
}
}
এখানে:
http.get()
ব্যবহার করে ডেটা ফেচ করার চেষ্টা করা হচ্ছে। যদি কোন ত্রুটি ঘটে, তবে catchError
অপারেটরটি তা ধরবে এবং একটি নতুন ত্রুটি রিটার্ন করবে।throwError()
ব্যবহার করে আমরা একটি কাস্টম ত্রুটি ছুঁড়ে দিয়েছি।catchError
এর সাথে ব্যবহারকারী-friendly ত্রুটি বার্তা প্রদর্শনআসুন, এবার ত্রুটির বার্তা ব্যবহারকারীর জন্য আরও উপকারী ও বিস্তারিত উপায়ে প্রদর্শন করি।
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getData(): Observable<any> {
return this.http.get('https://api.example.com/data')
.pipe(
catchError(error => {
let errorMessage = 'Unknown error occurred!';
if (error.status === 0) {
errorMessage = 'Network error: Please check your internet connection.';
} else if (error.status === 404) {
errorMessage = 'Data not found!';
} else if (error.status === 500) {
errorMessage = 'Server error. Please try again later.';
}
console.error(errorMessage); // Console-এ ত্রুটি লগ করুন
return throwError(() => new Error(errorMessage)); // কাস্টম ত্রুটি বার্তা রিটার্ন
})
);
}
}
এখানে:
error.status
এর মাধ্যমে আমরা HTTP ত্রুটির ধরন চেক করছি এবং ত্রুটির ভিত্তিতে কাস্টম ত্রুটি বার্তা তৈরি করছি।throwError()
মাধ্যমে কাস্টম ত্রুটি বার্তা ক্লায়েন্টে পাঠানো হচ্ছে।এখন, আমাদের সার্ভিসে ত্রুটি হ্যান্ডলিং করার পর, আমরা কম্পোনেন্টে ত্রুটিগুলির উপর প্রতিক্রিয়া জানাতে পারি। এখানে, আমরা DataService
এর getData()
ফাংশন ব্যবহার করছি এবং ত্রুটি যদি ঘটে, তবে সেটি দেখানোর জন্য UI তে একটি মেসেজ প্রিন্ট করছি।
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
data: any;
errorMessage: string | null = null;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.getData().subscribe({
next: (response) => {
this.data = response;
},
error: (error) => {
this.errorMessage = error.message; // ত্রুটি বার্তা UI তে দেখানো
}
});
}
}
এখানে:
subscribe()
ব্যবহার করা হয়েছে যেটি ডেটা পাওয়ার পর next
হ্যান্ডলার কাজ করবে এবং ত্রুটি ঘটলে error
হ্যান্ডলার কার্যকর হবে।error.message
অ্যাক্সেস করে তা UI তে প্রদর্শন করা হচ্ছে।<div *ngIf="errorMessage" class="error-message">
{{ errorMessage }}
</div>
<div *ngIf="data">
<h1>Data:</h1>
<pre>{{ data | json }}</pre>
</div>
এখানে:
errorMessage
ভেরিয়েবলটি দেখানো হবে।data
এর মান JSON ফরম্যাটে প্রদর্শিত হবে।RxJS তে ত্রুটি হ্যান্ডলিং অত্যন্ত গুরুত্বপূর্ণ, বিশেষ করে যখন আপনি HTTP অনুরোধ বা অন্য ধরনের asynchronous অপারেশন চালান। catchError
এবং throwError
অপারেটরগুলো ত্রুটি হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয় এবং এই ত্রুটিগুলো কাস্টম বার্তা হিসেবে ব্যবহারকারীকে জানানো যায়। এই প্রক্রিয়াটি অ্যাপ্লিকেশনের ব্যবহারকারী অভিজ্ঞতাকে উন্নত করতে সাহায্য করে, কারণ আপনি ত্রুটি ঘটলে ব্যবহারকারীকে সঠিক এবং স্পষ্ট বার্তা দিতে পারেন।
Read more